﻿using System;
using System.Collections.Generic;
using System.Linq;
using Balloonerds.Algebra;

namespace RayTracer
{
    public class Union : Thing
    {
        public List<Thing> Objects { get; private set; }

        public Union()
        {
            Objects = new List<Thing>();
        }

        public Union(IEnumerable<Thing> objects)
            : base()
        {
            Objects.AddRange(objects);
        }

        public override Vector GetSurfaceNormal(Vector point)
        {
            throw new InvalidOperationException("This method should not be called in a union");
        }
        public override Intersection GetIntersection(Ray ray)
        {
            var intersections =
                from obj in Objects
                select obj.GetIntersection(ray);

            return (
                from isect in intersections
                where isect != null
                orderby isect.Distance
                select isect
                ).FirstOrDefault();
        }
        public override bool TestIntersection(Ray ray, double distance)
        {
            if (TestBoundaryIntersection(ray, distance))
                foreach (var obj in Objects)
                    if (obj.TestIntersection(ray, distance))
                        return true;

            return false;
        }

        public override Thing Translate(Vector position)
        {
            foreach (var obj in Objects)
                obj.Translate(position);

            return base.Translate(position);
        }
        public override Thing RotateX(double radians)
        {
            foreach (var obj in Objects)
                obj.RotateX(radians);

            return base.RotateX(radians);
        }
        public override Thing RotateY(double radians)
        {
            foreach (var obj in Objects)
                obj.RotateY(radians);

            return base.RotateY(radians);
        }
        public override Thing RotateZ(double radians)
        {
            foreach (var obj in Objects)
                obj.RotateZ(radians);

            return base.RotateZ(radians);
        }
    }
}
